package com.smsc.headend.connector.utils;

public class GxAddrUtil {
    /**
     * 参考amr取的地址
     * @param id
     * @return
     */
    public static long setDesId(int id) {
        if (id > 9999) {
            // 大于4位 用拓展地址计算法则 ，
            return setExtendDesId(id);
        }
        char highAddr = (char) (id / 128);
        char lowAddr = (char) (id % 128);
        return (1 << 17) + (highAddr << 9) + (lowAddr << 1) + 1;
    }


    /**
     * 扩展地址计算规则可以参考文档
     * @param id
     * @return
     */
    public static long setExtendDesId(int id) {
        int highAddr = id / 128;
        char lowAddr = (char) (id % 128);
        if (highAddr > 127) {
            char hignAddrHighBit = (char) (highAddr / 128);
            char hignAddrLowBit = (char) (highAddr % 128);
            if (hignAddrHighBit > 127) {
                char upHighBit = (char) (hignAddrHighBit / 128);
                char upHighLowBit = (char) (hignAddrHighBit % 128);
                return (1L << 31) + ((long) upHighBit << 25) + ((long) upHighLowBit << 17) + (hignAddrLowBit << 9) + (lowAddr << 1) + 1;
            }
            return (1L << 31) + ((long) hignAddrHighBit << 17) + (hignAddrLowBit << 9) + (lowAddr << 1) + 1;
        }
        return (1 << 17) + ((long) highAddr << 9) + (lowAddr << 1) + 1;
    }

    /**
     * 参考GXCommon里面getHDLCAddress进行反转的serverAddress
     * @param value
     * @return
     */
    public static int getHDLCServerAddress(long value) {
        if (value < 0X80) {
            return (byte) ((value & 0xFE) >>> 1);
        } else if (value < 0X400) {
            return (int)(((value & 0xFE) >>> 1) | ((value & 0xFE00) >>> 2));

        } else if (value < 0x10000000) {
            long tmp = value;
            tmp = ((tmp & 0xFE) >> 1) | ((tmp & 0xFE00) >> 2)
                    | ((tmp & 0xFE0000) >> 3) | ((tmp & 0xFE000000) >> 4);
            return (int) tmp;
        } else {
            long tmp = value;
            tmp = ((tmp & 0xFE) >> 1) | ((tmp & 0xFE00) >> 2)
                    | ((tmp & 0xFE0000) >> 3) | ((tmp & 0xFE000000) >> 4);
            return (int) tmp;
        }
//        throw new IllegalArgumentException("Wrong size.");
    }

    public static int getHDLCServerAddSize(long value) {
        if (value < 0X80) {
            return 1;
        } else if (value < 0X400) {
            return 2;

        } else if (value < 0x10000000) {
            return 4;
        }
        throw new IllegalArgumentException("Wrong size.");
    }
}
